﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace System.Collections.Data
{
    public interface IDataFilter
    {
        string DisplayText { get; }
        string ImagePath { get; }
        IEnumerable<IDataFilter> SubFilters { get; set; }
        ICategoryProvider CategoryProvider { get; }

        IEnumerable Categories { get; }
    }

    public abstract class DataFilterBase : IDataFilter
    {
        private IEnumerable m_items;
        public IEnumerable Items { get { return m_items; } set { m_items = value; } }

        public abstract string DisplayText { get; }

        public virtual string ImagePath
        {
            get { return string.Empty; }
        }

        public IEnumerable<IDataFilter> SubFilters
        {
            get;
            set;
        }

        public IEnumerable Categories { get { return GetCategories(); } }

        private ICategoryProvider m_CategoryProvider;
        public ICategoryProvider CategoryProvider
        {
            get { return m_CategoryProvider; }
        }

        public DataFilterBase(ICategoryProvider provider, IEnumerable items)
        {
            Items = items;
            m_CategoryProvider = provider;
        }

        protected virtual IEnumerable GetCategories()
        {
            return m_CategoryProvider.GetCategoryList(Items);
        }
    }

    public class DataFilterCollection : List<IDataFilter>
    {
    }

    public class DataFilterTest1 : DataFilterBase
    {
        public DataFilterTest1()
            : base(null, null)
        {
        }

        public override string DisplayText
        {
            get { return string.Format("{0}", this.GetType()); }
        }

        protected override IEnumerable GetCategories()
        {
            for (int i = 0; i < 4; i++)
                yield return string.Format("{0} {1}", this.GetType(), i);
        }
    }
    public class DataFilterTest2 : DataFilterBase
    {
        public DataFilterTest2()
            : base(null, null)
        {
        }

        public override string DisplayText
        {
            get { return string.Format("{0}", this.GetType()); }
        }

        protected override IEnumerable GetCategories()
        {
            for (int i = 0; i < 4; i++)
                yield return string.Format("{0} {1}", this.GetType(), i);
        }
    }
    public class DataFilterTest3 : DataFilterBase
    {
        public DataFilterTest3()
            : base(null, null)
        {
        }

        public override string DisplayText
        {
            get { return string.Format("{0}", this.GetType()); }
        }

        protected override IEnumerable GetCategories()
        {
            for (int i = 0; i < 4; i++)
                yield return string.Format("{0} {1}", this.GetType(), i);
        }
    }


    public class DataFilterCollectionTest : DataFilterCollection
    {
        public DataFilterCollectionTest()
        {
            this.Add(new DataFilterTest1());
            this.Add(new DataFilterTest2());
            this.Add(new DataFilterTest3());
        }
    }


















    public interface IDataFilterer : INotifyPropertyChanged
    {
        string DisplayText { get; }

        bool HasSubFilters { get; }

        bool IsFirstInStack { get; }

        bool IsLastInStack { get; set; }

        IEnumerable Items { get; }

        IList Results { get; }

        void RefreshResults();
        void RefreshSubFilters();

        IDataFilterer SelectedSubFilter {get;}

        List<IDataFilterer> SubFilters { get; }

        event EventHandler ResultsChanged;
    }

    
    public abstract class DataViewFiltererBase : INotifyPropertyChanged, IDataFilterer
    {
        #region Fields

        private bool _IsFirstInStack = false;
        private bool _IsLastInStack = false;
        private IEnumerable _Items = null;
        private IList _Results = null;

        #endregion Fields

        #region Constructors

        public DataViewFiltererBase()
        {
        }

        public DataViewFiltererBase(IEnumerable items)
        {
            Items = items;
        }

        #endregion Constructors

        #region Properties

        public abstract string DisplayText { get; }

        public bool HasSubFilters { get { return SubFilters != null && SubFilters.Count > 0; } }

        public bool IsFirstInStack
        {
            get { return _IsFirstInStack; }
            set
            {
                _IsFirstInStack = value;
                RaisePropertyChanged("IsFirstInStack");
            }
        }

        public bool IsLastInStack
        {
            get { return _IsLastInStack; }
            set
            {
                _IsLastInStack = value;
                RaisePropertyChanged("IsLastInStack");
            }
        }

        public IEnumerable Items
        {
            get { return _Items; }
            set
            {
                _Items = value;
                RaisePropertyChanged("Items");
            }
        }

        public IList Results
        {
            get { return _Results; }
            set
            {
                _Results = value;
                RaisePropertyChanged("Results");
                RaiseResultsChanged();
            }
        }

        #endregion Properties

        #region Public Methods

        public abstract void RefreshResults();
        public virtual void RefreshSubFilters()
        {
        }

        public override string ToString()
        {
            if (!string.IsNullOrEmpty(DisplayText)) return DisplayText;
            return base.ToString();
        }

        #endregion Public Methods



        #region ResultsChanged

        public event EventHandler ResultsChanged;

        private void RaiseResultsChanged()
        {
            if (ResultsChanged != null)
            {
                ResultsChanged(this, new EventArgs());
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;
        protected void RaisePropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        #endregion

        private IDataFilterer m_SelectedSubFilter;
        public IDataFilterer SelectedSubFilter
        {
            get { return m_SelectedSubFilter; }
            set
            {
                m_SelectedSubFilter = value;
                RefreshResults();
                RaisePropertyChanged("SelectedSubFilter");
            }
        }

        private List<IDataFilterer> m_SubFilters = new List<IDataFilterer>();
        public List<IDataFilterer> SubFilters
        {
            get { return m_SubFilters; }
            set { m_SubFilters = value; RaisePropertyChanged("SubFilters"); }
        }
    }

}
